package modelo;

/***
 * Clase que permita relizar una conexion a una BD utilizando
 * JDBC.
 *
 * Driver postgresql : http://jdbc.postgresql.org/download.html
 * Driver mysql      : http://www.mysql.com/products/connector/
 * Lista de drivers API JDBC : http://developers.sun.com/product/jdbc/drivers
 */

import java.sql.*;
import java.util.ArrayList;

public class Conexion {

	// Datos de conexion
	private final String driver = "org.postgresql.Driver";
	private final String name_db = "jdbc:postgresql://localhost:5432/parcial";
	private final String user_db = "postgres";
	private final String pass_db = "master";
	private Connection con;
	private PreparedStatement pst;

	/**
	 * Constructor que realiza la conexion cuando se instancia un objeto
	 * Conexion
	 */
	Conexion() {
		try {
			// Driver de conexion, en este caso estoy utilizando el de
			// postgresql
			Class.forName(driver);
			// Creo una conexion con la base de datos a partir de los datos de
			// conexion
			con = DriverManager.getConnection(name_db, user_db, pass_db);
		} catch (Exception e) {
			// Si ocurre un error lo capturo
			e.printStackTrace();
		}
	}

	/**
	 * A partir de una consulta SQL realizada por el usuario obtiene un
	 * resultado
	 *
	 * @param sql
	 * @return
	 */
	public void consulta(String sql) {
		// Declaracion en null del resultSet
		System.out.println("Consulta : " + sql + "\n");
		try {
			// Para contar los registros
			int registros = 0;
			// Preparo la sentencia sql a ejecutar
			pst = con.prepareStatement(sql);
			// Obtengo los datos de la consulta en un resultset
			ResultSet rs = pst.executeQuery();
			// Guardo los datos del ResultSet en un ResultSetMetadata para jugar
			// un poco mas
			ResultSetMetaData rsm = rs.getMetaData();

			// Obtengo los nombres de las columnas <img src="http://codesandtags.org/wp-includes/images/smilies/icon_biggrin.gif" alt=":D" class="wp-smiley">
			for (int i = 1; i <= rsm.getColumnCount(); i++) {
				System.out.print("" + rsm.getColumnName(i) + " | ");
			}
			System.out.println("");

			while (rs.next()) {
				for (int i = 1; i <= rsm.getColumnCount(); i++) {
					System.out.print(rs.getString(i) + " | ");
				}
				registros++;
				System.out.println("");
			}

			System.out.println("\nCantidad de registros : " + registros);
			System.out
					.println("------------------------------------------------- \n");
			// Libero los datos del PreparedStatement, automaticamente tambien
			// se libera el ResultSet
			pst.close();
		} catch (SQLException e) {
			// Capturo la excepcion en caso de error
			e.printStackTrace();
		}
	}

	/**
     * Se encarga de ejecutar sentencias DML del tipo : UPDATE, DELETE,
     * INSERT...
     *
     * @param sql
     */
    public String sentenciaDetalle(String sql) {
        // Declaracion en null del resultSet
        String detalle = "";
        detalle += "<div> Sentencia : <strong>" + sql + "</strong></div><br/>";
        int registros = 0;
        try {
            // Preparo la sentencia sql a ejecutar
            pst = con.prepareStatement(sql);
            // Obtengo los datos de la consulta en un resultset
            // Para contar los registros afectados
            registros = pst.executeUpdate();
            if(sql.contains("UPDATE") || sql.contains("update") ||
               sql.contains("INSERT") || sql.contains("insert") ||
               sql.contains("DELETE") || sql.contains("delete")
                    ){
                detalle += "Cantidad de registros afectados : <strong>" +
                    registros + "</strong>";
            }
            // Libero los datos del PreparedStatement, automaticamente tambien
            // se libera el ResultSet
            pst.close();
        } catch (SQLException e) {
            // Capturo la excepcion en caso de error
            e.printStackTrace();
            detalle += e.getMessage();
        }
        
        return detalle;
    }
	
	
	/**
	 * Obtiene un ArrayList
	 * @param sql
	 * @return
	 */
	public ArrayList<String> getConsulta(String sql) {
        // Declaracion en null del resultSet
        System.out.println("Consulta : " + sql + "\n");
        // Para guardar los registros
        ArrayList<String> datos = new ArrayList();
        try {
            // Preparo la sentencia sql a ejecutar
            pst = con.prepareStatement(sql);
            // Obtengo los datos de la consulta en un resultset
            ResultSet rs = pst.executeQuery();
            // Guardo los datos del ResultSet en un ResultSetMetadata para jugar
            // un poco mas
            ResultSetMetaData rsm = rs.getMetaData();
            while (rs.next()) {
                StringBuilder linea = new StringBuilder();
                for (int i = 1; i <= rsm.getColumnCount(); i++) {
                    linea.append(rs.getString(i)).append(";");
                }
                datos.add(linea.toString());
            }

            pst.close();
        } catch (SQLException e) {
            // Capturo la excepcion en caso de error
            e.printStackTrace();
        }
        return datos;
    }

	/**
	 * Metodo que permite cerrar la conexion realizada a la BD
	 */
	public void desconectar() {
		try {
			// Cierro todas las conexiones con la base de datos
			// Automaticamente libero memoria y cierro las conexiones abiertas
			// en el objeto Connection
			con.close();
		} catch (Exception e) {
			// Controlo cualquier excepcion generada durante el cierre de la
			// conexion
			e.printStackTrace();
		}
	}		

}
